package com.ht.api.bigtask.impl.qywx;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import com.ht.api.bigtask.BaseBigTask;
import com.ht.api.db.Db;
import com.ht.api.db.DbConfig;
import com.ht.api.db.DbList;
import com.ht.api.db.Entity;
import com.ht.api.db.StreamLoadConfig;
import com.ht.api.open.OpenUtil;
import com.ht.api.util.HtTagUtil;
import com.ht.api.util.HtTagUtil.TagBean;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * 创建朋友圈分区标签
 * @author asq
 * @createTime 2025年3月24日 13:39:58
 */
@Slf4j
public class CreateMomentTag extends BaseBigTask {
	/** 发朋友圈时，同一客服下面最多能发给5000个粉丝 */
	private static final int MAX = 5000;
	/** 标签组名称 */
	private static final String TAG_GROUP_NAME = "朋友圈分区";
	/** 接口ID：查询企业客户标签 */
	private static final long API_ID_QUERY = 1896075908998107136L;
	/** 接口ID：添加企业客户标签 */
	private static final long API_ID_ADD = 1896076213701709824L;
	/** 接口ID：删除企业客户标签 */
	private static final long API_ID_DEL = 1896076815693385728L;
	/** 存储每个客服的朋友圈分区值 */
	private static final Map<String, Integer> partitionMap = new HashMap<>();

	@Override
	protected void doExecute(String appId, JSONObject context, Entity bean) {
		DataSource ds = getTenantDs(appId);
		StreamLoadConfig streamLoadConfig = DbConfig.getStreamLoadConfigByDataSource(ds);
		
		// 任务进度，重启项目时需要从上次进度恢复执行，而不是从头执行
		int process = getPageNum();
		
		// 1. 遍历所有客服，给每个客服创建朋友圈分区标签数据
		if (process == 0) {
			log.info("[CreateMomentTag]开始创建朋友圈分区标签数据");
			List<Entity> list = new ArrayList<>();
			DbList wxWorkuserList = Db.createSqlParser("wx_workuser").query(ds);
			wxWorkuserList.stream().forEach(wxWorkuser -> {
				list.addAll(createTag(ds, appId, wxWorkuser, 1));
			});
			Db.insertBatchWithStream(streamLoadConfig, list);
			log.info("[CreateMomentTag]朋友圈分区标签数据创建完成");
			
			// 记录任务进度
			saveInfo(PAGE_NUM_NAME, 1, bean);
		} else {
			log.info("[CreateMomentTag]恢复进度，跳过创建朋友圈分区标签数据");
		}
		
		// 2. 删除有可能存在的之前创建的标签组
		delOldTagGroup(appId);
		
		// 3. 调用企微接口创建标签
		if (process <= 1) {
			DbList wxMomentTagList = Db.createSqlParser("wx_moment_tag").where("status", 0).query(ds);
			
			if (!wxMomentTagList.isEmpty()) {
				// 调用接口创建标签
				JSONArray tagArr = JSONUtil.createArray();
				JSONObject param = JSONUtil.createObj();
				param.set("group_name", TAG_GROUP_NAME);
				param.set("order", 0);
				param.set("tag", tagArr);
				for (int i = 0; i < wxMomentTagList.size(); i++) {
					Entity wxMomentTag = wxMomentTagList.get(i);
					String tagName = wxMomentTag.getStr("tag_name");
					tagArr.add(JSONUtil.createObj().set("name", tagName));
				}
				log.info("[CreateMomentTag]开始创建企微标签，总数:{}", wxMomentTagList.size());
				String str2 = OpenUtil.callByNoAssemble(appId, API_ID_ADD, param);
				
				// 如果企微接口调用成功，则立即标记此标签已创建
				JSONObject obj2 = JSONUtil.parseObj(str2);
				if (obj2.getInt("errcode") == 0) {
					JSONArray wxTagArr = obj2.getByPath("tag_group.tag", JSONArray.class);
					for (int i = 0; i < wxTagArr.size(); i++) {
						JSONObject wxTag = wxTagArr.getJSONObject(i);
						
						Entity wxMomentTag = wxMomentTagList.get(i);
						wxMomentTag.set("tag_id", wxTag.getStr("id"));
						wxMomentTag.set("status", 1);
					}
					
					Db.insertBatchWithStream(streamLoadConfig, wxMomentTagList);
					log.info("[CreateMomentTag]创建标签成功，总数:{}", wxMomentTagList.size());
				}
			}
			
			// 记录任务进度
			saveInfo(PAGE_NUM_NAME, 2, bean);
		} else {
			log.info("[CreateMomentTag]恢复进度，跳过创建企微标签");
		}
		
		// 4. 调用企微接口打标签
		if (process <= 2) {
			DbList wxMomentTagList = Db.createSqlParser("wx_moment_tag").where("status", 1).query(ds);
			List<TagBean> tagList = new ArrayList<>();
			for (int i = 0; i < wxMomentTagList.size(); i++) {
				Entity wxMomentTag = wxMomentTagList.get(i);
				String tagId = wxMomentTag.getStr("tag_id");
				
				// 查询此标签对应的外部用户列表
				DbList wxWorkuserCustomerList = Db.createSqlParser("wx_workuser_customer")
				.where("userid", wxMomentTag.getStr("userid"))
				.where("type", 1)
				.where("moment_partition", wxMomentTag.getInt("moment_partition"))
				.query(ds);
			
				// 打标签
				JSONArray addTagArr = JSONUtil.createArray();
				addTagArr.add(tagId);
				wxWorkuserCustomerList.stream().forEach(b -> {
					TagBean tagBean = TagBean.builder()
							.appId(appId)
							.userid(b.getStr("userid"))
							.externalUserid(b.getStr("external_userid"))
							.tags(addTagArr)
							.build();
					tagList.add(tagBean);
				});
				
				// 记录任务进度
				saveInfo(PAGE_NUM_NAME, 3, bean);
			}
			
			if (!tagList.isEmpty()) {
				log.info("[CreateMomentTag]开始打标，总标签数:{}", wxMomentTagList.size());
				HtTagUtil.tag(tagList, () -> {
					log.info("[CreateMomentTag]打标完成，总标签数:{}", wxMomentTagList.size());
					wxMomentTagList.stream().forEach(wxMomentTag -> wxMomentTag.set("status", 2));
					Db.insertBatchWithStream(streamLoadConfig, wxMomentTagList);
				});
			}
		} else {
			log.info("[CreateMomentTag]恢复进度，跳过打标");
		}
	}

	/**
	 * 删除之前创建的朋友圈标签组，以便从头开始
	 * @param appId 应用ID
	 */
	private void delOldTagGroup(String appId) {
		String str = OpenUtil.call(appId, API_ID_QUERY, JSONUtil.createObj());
		JSONObject obj = JSONUtil.parseObj(str);
		String groupId = null;
		if (obj.getInt("errcode") == 0) {
			JSONArray tagGroupArr = obj.getJSONArray("tag_group");
			for (int i = 0; i < tagGroupArr.size(); i++) {
				JSONObject tagGroup = tagGroupArr.getJSONObject(i);
				String groupName = tagGroup.getStr("group_name");
				if (TAG_GROUP_NAME.equals(groupName)) {
					groupId = tagGroup.getStr("group_id");
					break;
				}
			}
		}
		if (groupId != null) {
			JSONArray groupIdArr = JSONUtil.createArray();
			groupIdArr.add(groupId);
			JSONObject param = JSONUtil.createObj();
			param.set("group_id", groupIdArr);
			OpenUtil.call(appId, API_ID_DEL, param);
			log.info("[CreateMomentTag]删除之前创建的朋友圈企微标签");
		}
	}

	/**
	 * 根据客服创建朋友圈分组标签
	 * @param ds
	 * @param appId
	 * @param wxWorkuser
	 * @param pageNum
	 * @return 返回需要保存到数据库的Entity集合
	 */
	private List<Entity> createTag(DataSource ds, String appId, Entity wxWorkuser, int pageNum) {
		List<Entity> list = new ArrayList<>();
		String userid = wxWorkuser.getStr("userid");
		
		// 查询客服的客户列表，5000个为一组
		DbList wxWorkuserCustomerList = Db.createSqlParser("wx_workuser_customer")
				.where("userid", userid).where("type", 1)
				.limit(pageNum, MAX).order("main_id", "asc").query(ds);
		if (!wxWorkuserCustomerList.isEmpty()) {
			// 查询客服的当前分区值
			int newPartition = getPartition(userid, pageNum);
			
			// 创建朋友圈标签表数据
			String tagName = String.format("%s_%s", wxWorkuser.getMainId(), newPartition);
			Entity wxMomentTag = Db.createEntity("wx_moment_tag");
			wxMomentTag.set("appid", appId);
			wxMomentTag.set("userid", userid);
			wxMomentTag.set("moment_partition", newPartition);
			wxMomentTag.set("tag_name", tagName);
			wxMomentTag.set("status", 0);
			list.add(wxMomentTag);
			
			// 所有外部用户标记分区值
			wxWorkuserCustomerList.stream().forEach(b -> {
				b.set("moment_partition", newPartition);
				list.add(b);
			});
			
			// 递归下一分区
			list.addAll(createTag(ds, appId, wxWorkuser, ++pageNum));
		}
		return list;
	}

	/**
	 * 获取缓存中的分区值
	 * @param userid 客服ID
	 * @param pageNum 分区页码
	 * @return
	 */
	private int getPartition(String userid, int pageNum) {
		String key = String.format("%s_%s", userid, pageNum);
		Integer partition = partitionMap.get(key);
		if (partition != null) {
			return partition;
		} else if (pageNum > 1){
			int prePartition = getPartition(userid, --pageNum);
			int newPartition = prePartition + 1;
			partitionMap.put(key, newPartition);
			return newPartition;
		} else {
			return 1;
		}
	}
}
